今天的題目來源,同樣是 stack overflow,標題是:「Gitlab CICD: use functions inside gitlab-ci.yml」,在 GitLab CI/CD 裡頭,如何在 .gitlab-ci.yml
裡頭用 function ? 原始問題是,提問者有一個使用 curl 發訊息到 teams 的 script,在 Job 的 Script 裡頭會反覆的一直使用,如下:
image:
name: hashicorp/terraform
before_script:
- export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")
stages:
- validate
- plan
validate:
stage: validate
script:
- terraform validate
- 'curl --request POST --header "Authorization: Bearer $bearer" --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
variables:
msg: "Example1"
plan:
stage: plan
script:
- terraform validate
- 'curl --request POST --header "Authorization: Bearer $bearer" --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
variables:
msg: "Example2"
提問者已經試著在 .gitlab-ci.yml
裡,使用 anchor 的方法在 .gitlab-ci.yml
裡重複使用,如下:
image:
name: hashicorp/terraform
before_script:
- export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")
.send_message: &send_message
script:
- 'curl --request POST --header "Authorization: Bearer $bearer" --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
stages:
- validate
- plan
validate:
stage: validate
script:
- terraform validate
- &send_message
variables:
msg: "Example1"
plan:
stage: plan
script:
- terraform validate
- &send_message
variables:
msg: "Example2"
但還是想詢問,也沒有更好的方法可以像使用 function,在 .gitlab-ci.yml
反覆使用重複的段落。
原提問者在自己的實驗中,其實已經透過 Anchor 的方法,在 .gitlab-ci.yml
中重複的使用 send_message
,但因為是使用 Anchor,其特性上必須在同一個 CI/CD YAML 中,所以,如果整個 CI/CD YAML 越來越龐大,開始進行拆分,這時候 send_message
就必須在需要使用的 YAML 中,重複一次,才能使用,使用 Anchor 來重複使用,看起來就不像原提問者想要的 function。
!reference
解決這問題?在 stack overflow 上看到這題目時,GitLab 的 !reference
(Optimize GitLab CI/CD configuration files - !reference tags | GitLab Docs)語法,剛推出沒多久,在這情境下,剛好符合提問者使用,於是可以將提問者的題目修改為如下:
# file name: function.yml
.send_message:
script:
- echo 'curl --request POST --header "Authorization Bearer $bearer" --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
# file name: .gitlab-ci.yml
include:
- local: functions.yml
default:
image: ubuntu:24.04
before_script:
- export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")
stages:
- validate
- plan
validate:
stage: validate
script:
- echo "terraform validate"
- !reference [.send_message, script]
variables:
msg: "Example1"
plan:
stage: plan
script:
- echo "terraform validate"
- !reference [.send_message, script]
variables:
msg: "Example2"
GitLab CI/CD YAML 的 !reference
語法特性,就是為了解決 Anchor 無法跨 YAML 檔案使用而誕生的方法,它可以利用 include
的載入該 YAML,接著透過 !reference
語法來重複使用,縱使是在 script
裡,也可以直接載入使用,只要有 include
檔案進來,就可以到處使用,剛好可以適用原提問者想解決的問題。
今天的題目,是我在 stack overflow 上目前回答過與 GitLab 相關題目中,被按加分最多的題目,眼尖的讀者,可能可以發現,其實 !reference
這個方法,已經在 Day02 的內容中有提到,但為什麼還想要再說一次呢?
因為在 Day02 中,是直接以介紹功能與特性的方法介紹,但是,在今天的題目中,是直接解答問題的角度來找到符合的特性,因為角度不太一樣,所以會想用不同的角度來看 !reference
的特性。如果是你,你會想怎麼解決原提問者的問題呢?
我是墨嗓(陳佑竹),期待這次的內容能帶給你實用的啟發與幫助。